java 集合类源码分析--list接口
第一点:介绍list 接口
List 是一种集合。以数据结构的中定义它是一种线性的结构。
1)除了第一个元素以外,每个元素都有且只有唯一的一个前驱。
2)除了最后一个元素以外每个一元素有且只有一个后继。
3)集合中必须存在第一个元素还有最后一个元素。
list在java中是表现为一种接口,通过不同的实现方式来实现具体数据存在方式 (arraylist linkedlist vector arrays.aslist,collection.ncopies,collections empty_list)
下面是jdk 中list接口相关的源码
package java.util; public interface List<E> extends Collection<E> { //返回list中元素的个数,如果集合中的数个数超过int的最大值,则返回int的最大值 int size(); //判断集合是否为空,空返回true boolean isEmpty(); //判断集合是不是至少有一个相关的元素o==null;e==null;o.equals(e) //如果查找的元素类型不对会抛出ClassCastException ,若查找的元素为空则抛出//NullPointerException boolean contains(Object o); //返回list迭代器 Iterator<E> iterator(); //返回此集合中所有的元素,实现这个方法源码的中的解释是 实现这个方法是返回一个全新的数组,线程安全的,可以对其修改不影响原来的元素 Object[] toArray(); //针对上一个方法 toArray ,返回的是Object数组,此时是无法进行数组的强制类//型转换的 因此得不到实际的类型。 //此方式相当对其的补充 源码中给出的例子 String[] y = x.toArray(new //String[0]) 其中x为String 类型的list <T> T[] toArray(T[] a); // Modification Operations // 在list的末尾增加元素 * * @param e element to be appended to this list * @return <tt>true</tt> (as specified by {@link Collection#add}) * @throws UnsupportedOperationException if the <tt>add</tt> operation * is not supported by this list * @throws ClassCastException if the class of the specified element * prevents it from being added to this list * @throws NullPointerException if the specified element is null and this * list does not permit null elements * @throws IllegalArgumentException if some property of this element * prevents it from being added to this list */ boolean add(E e); //移除元素 集合中第一次出现的元素。如2、2、3 移除2后为2、3 * @param o element to be removed from this list, if present * @return <tt>true</tt> if this list contained the specified element * @throws ClassCastException if the type of the specified element * is incompatible with this list * @throws UnsupportedOperationException if the <tt>remove</tt> operation * is not supported by this list */ boolean remove(Object o); //是否包含集合中的所有元素 boolean containsAll(Collection<?> c); //增加集合中的元素到list中去 boolean addAll(Collection<? extends E> c); //从c中的第几个元素起插入到list boolean addAll(int index, Collection<? extends E> c); //删除list包含c中的元素 boolean removeAll(Collection<?> c); //删除除了c中元素的其他元素 boolean retainAll(Collection<?> c); //清除list中的元素 void clear(); boolean equals(Object o); /** * <pre> * int hashCode = 1; * for (E e : list) * hashCode = 31*hashCode + (e==null ? 0 : e.hashCode()); */ int hashCode(); // Positional Access Operations //得到指定位置的元素 E get(int index); //替换制定位置元素,返回被替换元素 E set(int index, E element); //制定位置增加元素,其他元素向右移动 void add(int index, E element); //删除指定位置的元素,若超出集合长度抛出IndexOutOfBoundsException //返回删除的元素 E remove(int index); // Search Operations //查找元素位置在list 中,若元素不存在返回-1 int indexOf(Object o); //查找元素在集合中最后一次出现的位置 int lastIndexOf(Object o); ListIterator<E> listIterator(); //从index位置开始遍历 ListIterator<E> listIterator(int index); // View //从formIndex 开始到toIndex截止的子表 List<E> subList(int fromIndex, int toIndex); }
Java中Arrays的asList()方法 可以将 数组转为List 但是,这个数组类型必须是 引用类型的,最近在用Arrays的asList()生成的List时,List元素的个数时而不正确。
Java代码
//经多次测试,只要传递的基本类型的数组,生成List的元素个数均为1
char arrc = {'a','b'};
int arrint = {1,2,4};
Arrays.asList(arrc).size() ;// 结果为1;
Arrays.asList(arrint ).size() ;//结果为1;
//传递对象数组,元素个数正确。
String arrstr = {"a","b","java","spring","hadoop","lucene"};
Arrays.asList(arrstr ).size() ;//结果为6;
跟源码:
Java代码
public static <T> List<T> asList(T... a) { //即在此处基本数据类型的数组在此处 被当作一个//对象而非数组,而引用类型的数组被解析成了数组。
return new ArrayList<T>(a);
}
继续跟,Arrays的私有内部类ArrayList (没搞明白,为什么这里也起名为ArrayList)
private final E[] a;
ArrayList(E[] array) {
if (array==null)
throw new NullPointerException();
a = array;
}
public int size() {
return a.length;
}
//测试
public class TestArray {
PrintStream out = System.out;
@Test
public void array() {
char[] arrc = {'a','b','c','d','e'};
out.println("传递char数组:");
print(arrc);
out.println("直接传递:");
print('a','b','c','d','e');
out.println("----------------------------");
int[] arri = {1,2,3,4,5,6,7};
out.println("传递int数组:");
print(arri);
out.println("直接传递:");
print(1,2,3,4,5,6,7);
out.println("----------------------------");
Integer[] arrInt = {1,2,3,4,5,6,7};
out.println("传递Integer数组:");
print(arrInt);
out.println("直接传递:");
print(1,2,3,4,5,6,7);
out.println("----------------------------");
String[] arrs = {"a","b","c","d","e"};
out.println("传递String数组:");
print(arrs);
out.println("直接传递:");
print('a','b','c','d','e');
out.println("----------------------------");
}
public void print(Object...arr){
out.print("内容:"+Arrays.toString(arr));
out.println("\t\t数组长度:"+arr.length+" ");
}
}
输出结果为:
传递char数组:
内容:[[C@defa1a] 数组长度:1
直接传递:
内容:[a, b, c, d, e] 数组长度:5
----------------------------
传递int数组:
内容:[[I@f5da06] 数组长度:1
直接传递:
内容:[1, 2, 3, 4, 5, 6, 7] 数组长度:7
----------------------------
传递Integer数组:
内容:[1, 2, 3, 4, 5, 6, 7] 数组长度:7
直接传递:
内容:[1, 2, 3, 4, 5, 6, 7] 数组长度:7
----------------------------
传递String数组:
内容:[a, b, c, d, e] 数组长度:5
直接传递:
内容:[a, b, c, d, e] 数组长度:5
----------------------------
如果直接传递数组,基本类型数组将被视为一个对象而不会被解析成数组,如果直接传递参数将能正常解析。因此传递基本类型数组时强烈建议转为其封装类对象的数组 int ->Integer ,long->Long …………。(未对其封装)
Collections.ncopyies(int n,T o) 方法用于返回一个不可变列表组成的n个拷贝的指定对象。
以下是java.util.Collections.ncopies()方法的声明。
public static <T> List<T> nCopies(int n, T o)
参数
-
n-- 在返回列表中元素的个数。
-
o-- 在返回列表中反复出现的元素。
返回值
方法调用返回的不可变列表组成的n个拷贝的指定对象。
异常
-
IllegalArgumentException-- 如果 n < 0 此异常被抛出.
例子
下面的例子显示java.util.Collections.ncopies()方法的使用
package com.yiibai;
import java.util.*;
public class CollectionsDemo {
public static void main(String[] args) {
// create a list with n copies
List list = Collections.nCopies(5, "tuitorial Point");
// create an iterator
Iterator itr = list.iterator();
System.out.println("Values are :");
while (itr.hasNext()){
System.out.println(itr.next());
}
}
}
现在编译和运行上面的代码示例,将产生以下结果。
Values are :
tuitorial Point
tuitorial Point
tuitorial Point
tuitorial Point
tuitorial Point